home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / lang_c / cppdll / console.cxx < prev    next >
Text File  |  1990-03-07  |  11KB  |  384 lines

  1. // written by A.P.Mazur
  2.  
  3. #include "console.hxx"
  4. #undef NULL
  5. #include "fontsel.h"
  6. #include "colorsel.h"
  7. #include "stdlib.h"
  8. #include "stdio.h"
  9. #include "defines.h"
  10. #include <string.h>
  11.  
  12. #define  MEM_FLAG      (LMEM_FIXED)
  13. #define  COLOR_NOTIFY  302
  14. #define  FONT_NOTIFY   303
  15. typedef  int (FAR PASCAL *CALLBACK)(...); 
  16.  
  17.  
  18. extern "C" {
  19.    export long FAR PASCAL ConsoleWindowProc(HWND hWnd,WORD message,WORD  wParam,LONG lParam );
  20.    local  void ConsolePaint(HWND hWnd,LPPAINTSTRUCT lpPs);
  21.    local  void updateScrollBars(HWND hWnd);
  22. }
  23.  
  24. local       HANDLE hInst       = NULL;
  25. local const char   className[] = "A C++ Console";
  26. local       char   buffer[30]; // temporary buffer used for conversions
  27.  
  28. BOOL    Console::registered = FALSE;
  29.  
  30. Console::Console(LPSTR caption)
  31. {
  32. WNDCLASS   TemplateClass;
  33.  
  34.    background            = RGB(0xff,0xff,0xff);
  35.    foreground            = RGB(0,0,0);
  36.    firstLine             =  0;
  37.    count                 = -1;
  38.    textHeight            = 14;
  39.    font.lfHeight         =  14;
  40.    font.lfWidth          =  8;
  41.    font.lfEscapement     =  0;
  42.    font.lfOrientation    =  0;
  43.    font.lfWeight         = 400;
  44.    font.lfItalic         =  0;
  45.    font.lfUnderline      =  0;
  46.    font.lfStrikeOut      =  0;
  47.    font.lfCharSet        =  0;
  48.    font.lfOutPrecision   =  OUT_DEFAULT_PRECIS;
  49.    font.lfClipPrecision  =  CLIP_DEFAULT_PRECIS;
  50.    font.lfQuality        =  DEFAULT_QUALITY;
  51.    font.lfPitchAndFamily =  FF_DONTCARE | DEFAULT_PITCH;
  52.    strcpy((char *)font.lfFaceName,"System");
  53.  
  54.     if (!registered) {
  55.       TemplateClass.hCursor        = LoadCursor(NULL, IDC_ARROW);
  56.       TemplateClass.hIcon          = LoadIcon(hInst,"icon");
  57.       TemplateClass.cbClsExtra     = 0;
  58.       TemplateClass.cbWndExtra     = 4;
  59.       TemplateClass.lpszMenuName   = "menu";
  60.       TemplateClass.lpszClassName  = (LPSTR)className;
  61.       TemplateClass.hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
  62.       TemplateClass.hInstance      = hInst;
  63.       TemplateClass.lpfnWndProc    = ConsoleWindowProc;
  64.       TemplateClass.style          = CS_VREDRAW | CS_HREDRAW;
  65.    
  66.      if (!RegisterClass((LPWNDCLASS)&TemplateClass))
  67.         return ;
  68.      registered = TRUE;
  69.     }
  70.     handle = CreateWindow((LPSTR)className,
  71.                          (LPSTR)caption,
  72.                          WS_OVERLAPPEDWINDOW | WS_VSCROLL,
  73.                          CW_USEDEFAULT, 
  74.                          CW_USEDEFAULT, 
  75.                          CW_USEDEFAULT, 
  76.                          CW_USEDEFAULT,
  77.                          (HWND)NULL,
  78.                          (HMENU)NULL,
  79.                          (HANDLE)hInst,
  80.                          (LPSTR)NULL
  81.                        );
  82.      SetWindowLong(handle,0,(long)this);
  83.      newLine();
  84. }
  85.  
  86. Console::~Console()
  87. {
  88.    if (IsWindow(handle)) {
  89.       DestroyWindow(handle);
  90.       handle = NULL;
  91.    }
  92. }
  93.  
  94. int Console::runModeless()
  95. {
  96. MSG   msg;
  97.    while (GetMessage((LPMSG)&msg, NULL, 0, 0)) {
  98.             TranslateMessage((LPMSG)&msg);
  99.             DispatchMessage((LPMSG)&msg);
  100.    }
  101.    return (int)msg.wParam;
  102. }
  103.  
  104. void Console::show(short mode)
  105. {
  106.    ShowWindow( handle, mode );
  107. }
  108.  
  109. void Console::update()
  110. {
  111.    UpdateWindow( handle );
  112. }
  113.  
  114. void Console::newLine()
  115. {
  116.    if (count >= MAX_LINES - 1) {
  117.       if (text[0])
  118.          LocalFree(text[0]);
  119.       for(int i=0; i < count; i++) {
  120.          text  [i] = text  [i+1];
  121.          length[i] = length[i+1];
  122.       }
  123.    }
  124.    else
  125.       count++;
  126.    text[count]   = LocalAlloc(MEM_FLAG | LMEM_ZEROINIT,2);
  127.    length[count] = 0;
  128.    updateScrollBars(handle);
  129.    UpdateWindow(handle);
  130. }
  131.  
  132. Console& Console::operator << (LPSTR s)
  133. {
  134. char *line;
  135. char *target;
  136. HANDLE h,t;
  137.    if (s != NULL) {
  138.       t = h = LocalAlloc(MEM_FLAG | LMEM_ZEROINIT,strlen(s)+length[count]+2);
  139.       if (h) {
  140.          line = LocalLock(text[count]);
  141.          target = LocalLock(h);
  142.          strcpy(target,line);
  143.          strcpy(target+length[count],s);
  144.          LocalUnlock(text[count]);
  145.          LocalUnlock(h);
  146.          length[count] += strlen(s);
  147.          LocalFree(text[count]);
  148.          text[count] = t;
  149.       }
  150.    }
  151.    return *this;
  152. }
  153.  
  154. Console& Console::operator <<(char c)
  155. {
  156.    buffer[0] = c;
  157.    buffer[1] = '\0';
  158.    return (*this << buffer);
  159. }
  160.  
  161. Console& Console::operator <<(int i)
  162. {
  163.    itoa(i,buffer,10);
  164.    return (*this << buffer);
  165. }
  166.  
  167. Console& Console::operator <<(long l)
  168. {
  169.    sprintf(buffer,"%ld",l);
  170.    return (*this << buffer);
  171. }
  172.  
  173. Console& Console::operator <<(DWORD l)
  174. {
  175.    sprintf(buffer,"%lu",l);
  176.    return (*this << buffer);
  177. }
  178.  
  179. Console& Console::operator <<(WORD l)
  180. {
  181.    sprintf(buffer,"%u",l);
  182.    return (*this << buffer);
  183. }
  184.  
  185. Console& Console::operator << (double d)
  186. {
  187.    sprintf(buffer,"%f",d);
  188.    return (*this << buffer);
  189. }
  190.  
  191. extern "C" {
  192. local void  updateScrollBars(HWND hWnd)
  193. {
  194. Console far *self;
  195.  
  196.    self = (Console far *)GetWindowLong(hWnd,0);
  197.    SetScrollRange(hWnd,SB_VERT,0,self->count-1,FALSE);
  198.    SetScrollPos(hWnd,SB_VERT,self->firstLine,TRUE);
  199. }
  200.  
  201. local  void scrollDown(HWND hWnd,int lines)
  202. {
  203. Console far *self;
  204.  
  205.    self = (Console far *)GetWindowLong(hWnd,0);
  206.    if (self->firstLine == self->count - 1)
  207.       return;
  208.    self->firstLine += lines;
  209.    if (self->firstLine > self->count - 1)
  210.       self->firstLine = self->count - 1;
  211.    updateScrollBars(hWnd);
  212.    InvalidateRect(hWnd,NULL,TRUE);
  213.    UpdateWindow(hWnd);
  214. }
  215.  
  216. local  void scrollUp(HWND hWnd,int lines)
  217. {
  218. Console far *self;
  219.    self = (Console far *)GetWindowLong(hWnd,0);
  220.    if (self->firstLine == 0)
  221.       return;
  222.    self->firstLine -= lines;
  223.    if (self->firstLine < 0)
  224.       self->firstLine = 0;
  225.    updateScrollBars(hWnd);
  226.    InvalidateRect(hWnd,NULL,TRUE);
  227.    UpdateWindow(hWnd);
  228. }
  229.  
  230. export long FAR PASCAL ConsoleWindowProc(HWND hWnd,WORD message,WORD  wParam,LONG lParam )
  231. {
  232. PAINTSTRUCT ps;
  233. Console far *self;
  234.  
  235.    self = (Console far *)GetWindowLong(hWnd,0);
  236.    switch (message) {
  237.     case WM_DESTROY:
  238.         PostQuitMessage( 0 );
  239.         break;
  240.  
  241.     case WM_PAINT:
  242.             BeginPaint(hWnd,&ps);
  243.             ConsolePaint(hWnd,&ps);
  244.             EndPaint(hWnd,&ps);
  245.             break;
  246.  
  247.     case WM_VSCROLL:
  248.       switch (wParam) {
  249.        case SB_THUMBPOSITION:
  250.          self->firstLine = LOWORD(lParam);
  251.          scrollUp(hWnd,0);
  252.          break;
  253.  
  254.        case SB_BOTTOM:
  255.          self->firstLine = self->count - 1;
  256.          scrollUp(hWnd,0);
  257.          break;
  258.  
  259.        case SB_TOP:
  260.          self->firstLine = 0;
  261.          scrollUp(hWnd,0);
  262.          break;
  263.  
  264.        case SB_PAGEDOWN:
  265.          scrollDown(hWnd,16);
  266.          break;
  267.  
  268.        case SB_PAGEUP:
  269.          scrollUp(hWnd,16);
  270.          break;
  271.  
  272.        case SB_LINEDOWN:
  273.          scrollDown(hWnd,1);
  274.          break;
  275.  
  276.        case SB_LINEUP:
  277.          scrollUp(hWnd,1);
  278.          break;
  279.       };
  280.       break;
  281.             
  282.     case WM_COMMAND:
  283.             switch (wParam) {
  284.              case CHANGE_FONT:
  285.                         {
  286.                           HANDLE hLibrary = LoadLibrary("FONTSEL.DLL");
  287.                           if (hLibrary > 32) {
  288.                               CALLBACK lpSelectFont = (CALLBACK)GetProcAddress(hLibrary,"SelectFont");
  289.                               if (lpSelectFont != NULL){
  290.                                  HDC hDC = GetDC(hWnd);
  291.                                  (*lpSelectFont)(hWnd,hDC,FIXED_PITCH | VARIABLE_PITCH,(LPLOGFONT)&(self->font),FONT_NOTIFY);
  292.                                  ReleaseDC(hWnd,hDC);
  293.                               }
  294.                               FreeLibrary(hLibrary);
  295.                           }
  296.                         }
  297.                         break;
  298.  
  299.              case CHANGE_FOREGROUND:
  300.                         {
  301.                           HANDLE hLibrary = LoadLibrary("COLORSEL.DLL");
  302.                           if (hLibrary > 32) {
  303.                               CALLBACK lpSelectColor = (CALLBACK)GetProcAddress(hLibrary,"SelectColor");
  304.                               if (lpSelectColor != NULL)
  305.                                    (*lpSelectColor)(hWnd,(LONG FAR *) &(self->foreground),COLOR_NOTIFY);
  306.                               FreeLibrary(hLibrary);
  307.                           }
  308.                         }
  309.                   break;
  310.  
  311.              case CHANGE_BACKGROUND:
  312.                         {
  313.                           HANDLE hLibrary = LoadLibrary("COLORSEL.DLL");
  314.                           if (hLibrary > 32) {
  315.                               CALLBACK lpSelectColor = (CALLBACK)GetProcAddress(hLibrary,"SelectColor");
  316.                               if (lpSelectColor != NULL)
  317.                                    (*lpSelectColor)(hWnd,(LONG FAR *) &(self->background),COLOR_NOTIFY);
  318.                               FreeLibrary(hLibrary);
  319.                           }
  320.                         }
  321.                     break;
  322.  
  323.             case COLOR_NOTIFY:
  324.             case FONT_NOTIFY:
  325.                   UpdateWindow(hWnd);
  326.                   break;
  327.             }
  328.             break;
  329.     default:
  330.         return DefWindowProc(hWnd,message,wParam,lParam );
  331.         break;
  332.     }
  333.     return 0L;
  334. }
  335.  
  336. local  void ConsolePaint(HWND hWnd,LPPAINTSTRUCT lpPs)
  337. {           
  338. TEXTMETRIC  tm;
  339. char        *line;
  340. Console far *self;
  341. HANDLE      hLogFont;
  342. HANDLE      hLogFontOld;
  343. int         yPos;
  344.  
  345.     self = (Console far *)GetWindowLong(hWnd,0);
  346.  
  347.     hLogFont    = (HANDLE)CreateFontIndirect((LPLOGFONT)&(self->font));
  348.     hLogFontOld = SelectObject(lpPs->hdc,hLogFont);
  349.  
  350.                      /* get font parameters */
  351.     SetBkColor  (lpPs->hdc,self->background);
  352.     SetTextColor(lpPs->hdc,self->foreground);
  353.  
  354.     GetTextMetrics(lpPs->hdc,(LPTEXTMETRIC)&tm );
  355.     self->textHeight = tm.tmHeight + tm.tmExternalLeading;
  356.  
  357.    yPos = 3;    
  358.    for (int i=(self->firstLine); (i <= (self->count)) && (yPos < lpPs->rcPaint.bottom); i++) {
  359.       line = LocalLock((self->text)[i]);
  360.       if (line) {
  361.          if (((yPos + self->textHeight) > lpPs->rcPaint.top) &&
  362.              ((yPos) < lpPs->rcPaint.bottom))
  363.             TextOut( lpPs->hdc, 3,yPos,line,strlen(line));
  364.          yPos += self->textHeight;
  365.          LocalUnlock((self->text)[i]);
  366.       }
  367.    }
  368.    SelectObject( lpPs->hdc, hLogFontOld );
  369.    DeleteObject( hLogFont );
  370. }
  371.  
  372. export int FAR PASCAL 
  373. LibMain(HANDLE hInstance,WORD dataSeg,WORD heapSize)
  374. {
  375.   hInst = hInstance;
  376.   if  (heapSize  ==   0)
  377.     return 0;
  378.   return LocalInit(dataSeg,NULL,heapSize);
  379. }
  380.  
  381. } // end of "C" linkage
  382.  
  383.  
  384.